#pragma once
#include "base/function.hpp"
#include "MyRpc/rpccall.hpp"

#include <vector>

namespace myrpc::base{

class Rpc{
 public:
  Rpc();
  ~Rpc() = default;
  template<typename T>
  void Init_fun(uint32_t type,T&& func_body,rpc_callback&& cb = [](net_tools::net::Connect*,void*,unsigned int){;}){
    if(Rpc_type_is_available(type)){
      rpc_vec_[type].Init(typename detail::Traits_Ret_Arg<std::decay_t<T>>::Ret_Args(),
                          static_cast<typename detail::Traits_Ret_Arg<std::decay_t<T>>::T>(func_body),
                          std::forward<rpc_callback>(cb));
    }
  };
  unsigned int Call_fun(net_tools::net::Connect* connect,char* buf);
  uint32_t Analyze_uint(char* buf) const;
  static bool Rpc_type_is_available(uint32_t type){
    return type <= rpc_type_size_;
  };
 private:
  std::vector<Rpccall<>>                  rpc_vec_;
  const uint32_t                          head_size_ = sizeof(uint32_t);
  const uint32_t                          len_size_ = sizeof(uint32_t);
  static const uint32_t                   rpc_type_size_ = 3;
};

} // namespace myrpc::base